package com.youxin.chat.pay.service.channel.impl.ainong;

import com.alibaba.fastjson.JSONObject;

import com.youxin.base.BaseResultCode;
import com.youxin.chat.basic.dto.constant.SmsTypeEnum;
import com.youxin.chat.pay.enums.CashStatusEnum;
import com.youxin.chat.pay.enums.OrderStatusEnum;
import com.youxin.chat.pay.model.ChannelAccount;
import com.youxin.chat.pay.model.ChannelOrder;
import com.youxin.chat.pay.model.UserCash;
import com.youxin.chat.pay.model.UserRecharge;
import com.youxin.chat.pay.service.channel.IPayChannel;
import com.youxin.chat.pay.enums.PayChannelEnum;
import com.youxin.chat.pay.service.channel.entity.*;
import com.youxin.chat.pay.service.channel.impl.ainong.convert.AinongCovert;
import com.youxin.chat.pay.service.channel.impl.ainong.convert.AinongErrorTransfer;
import com.youxin.chat.pay.service.channel.impl.ainong.request.AinongDefray;
import com.youxin.chat.pay.service.channel.impl.ainong.request.AinongPay;
import com.youxin.chat.pay.service.channel.impl.ainong.util.AinongSignUtil;
import com.youxin.chat.pay.service.rpc.SmsService;
import com.youxin.chat.pay.utils.HttpClientUtil;
import com.youxin.utils.IPUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

import static com.youxin.common.constant.RedisKey.SMS_CODE_PREFIX;


@Component
public class AinongPayChannel implements IPayChannel {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private SmsService smsService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public ChannelResponse bindCard(String orderNo, ChannelBindCard channelBindCard, ChannelAccount channelAccount) {
        ChannelResponse response = new ChannelResponse(BaseResultCode.SUCCESS);
        String content = "您的短信验证码为%s,该短信验证码在3分钟内有效，此验证码勿提供给他人，请勿转发";
        smsService.sendSms(SmsTypeEnum.BIND_CARD.getType(), channelBindCard.getCardMobile(), content, IPUtil.ipToLong(channelBindCard.getUserIp()));
        response.setCode(BaseResultCode.SUCCESS);
        response.setStatus(1);
        String key = SMS_CODE_PREFIX + channelBindCard.getCardMobile() + "." + SmsTypeEnum.BIND_CARD.getType();
        response.setExt(key);
        return response;
    }

    @Override
    public ChannelResponse validateSms(ChannelBindCardSms channelBindCardSms, ChannelAccount channelAccount) {
        ChannelResponse response = new ChannelResponse(BaseResultCode.SUCCESS);
        String key = channelBindCardSms.getExt();
        String code = stringRedisTemplate.opsForValue().get(key);
        if (channelBindCardSms.getValidateCode().equals(code)) {
            response.setCode(BaseResultCode.SUCCESS);
            response.setStatus(1);
        } else {
            response.setCode(BaseResultCode.COMMON_FAIL);
            response.setErrorMsg("短信验证失败");
            return response;
        }
        return response;
    }

    @Override
    public boolean support(String channelCode) {
        return PayChannelEnum.AINONG.getChannelCode().equalsIgnoreCase(channelCode);
    }

    @Override
    public ChannelResponse pay(ChannelPay channelPay, ChannelAccount channelAccount) {
        ChannelResponse response = new ChannelResponse(BaseResultCode.SUCCESS);
        JSONObject data = AinongPay.buildReChargeRequest(channelPay, channelAccount);
        JSONObject request = AinongCovert.buildParams(data, channelAccount.getChannelAccount(), channelPay.getOrderNo());
        String sign = AinongSignUtil.buildSign(request, channelAccount.getRsaKeyPri());
        request.put("signature", sign);
        logger.info("{} 充值请求参数，data={}", channelAccount.getChannelCode(), request.toJSONString());
        String result;
        try {
            String url = channelAccount.getChannelUrl() + "/quickPay/payApply.do";
            result = HttpClientUtil.invokeHttpPost(url, request.toJSONString());
            logger.info("{} 充值请求完成，result={}", channelAccount.getChannelCode(), result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            boolean flag = AinongSignUtil.verifySign(result, channelAccount.getRsaKeyPub());
            ;
            if (!flag) {
                logger.error("{} 充值请求验签失败，result={}", channelAccount.getChannelCode(), result);
                response.setCode(BaseResultCode.COMMON_FAIL);
                response.setErrorMsg("请求接口异常");
                return response;
            }
            if ("0000".equalsIgnoreCase(jsonObject.getString("gateWayRespCode"))) {
                if (jsonObject.getJSONObject("data").getString("respCode").equalsIgnoreCase("000000")) {
                    String tn = jsonObject.getJSONObject("data").getString("tn");

                    Map<String, String> dataMap = new HashMap<>();
                    dataMap.put("tn", tn);
                    response.setCode(BaseResultCode.SUCCESS);
                    response.setStatus(1);
                    response.setResult(JSONObject.toJSONString(jsonObject));
                    response.setExt(JSONObject.toJSONString(dataMap));
                    return response;
                } else {
                    response = AinongErrorTransfer.buildErrorResult(jsonObject.getJSONObject("data").getString("respCode"), jsonObject.getJSONObject("data").getString("respMsg"));
                    response.setResult(result);
                    response.setStatus(OrderStatusEnum.PAY_FAIL.getStatus());
                }
            } else {
                response = AinongErrorTransfer.buildErrorResult(jsonObject.getJSONObject("data").getString("respCode"), jsonObject.getJSONObject("data").getString("respMsg"));
                response.setResult(result);
                response.setStatus(OrderStatusEnum.PAY_FAIL.getStatus());
            }
            /*if (!jsonObject.getString("respCode").equalsIgnoreCase("000000")) {

                response.setCode(BaseResultCode.COMMON_FAIL);
                response.setErrorMsg(jsonObject.getJSONObject("data").getString("respMsg"));
                return response;
            }
            String tn = jsonObject.getJSONObject("data").getString("tn");
            JSONObject smsData = new JSONObject();
            smsData.put("tn", tn);
            JSONObject smsRequest = AinongCovert.buildParams(data, channelAccount.getChannelAccount());
            String smsUrl = channelAccount.getChannelUrl() + "/quickPay/sendSms.do";
            sign = AinongSignUtil.buildSign(smsRequest, channelAccount.getRsaKeyPri());
            smsRequest.put("signature", sign);
            logger.info("{} 发送短信请求参数，data={}", channelAccount.getChannelCode(), smsRequest.toJSONString());
            result = HttpClientUtil.invokeHttpPost(smsUrl, request.toJSONString());
            logger.info("{} 发送短信完成，result={}", channelAccount.getChannelCode(), result);
            JSONObject smsObject = JSONObject.parseObject(result).getJSONObject("data");

            if (smsObject.getString("respCode").equalsIgnoreCase("000000")) {
                Map<String, String> dataMap = new HashMap<>();
                dataMap.put("tn", tn);
                response.setCode(BaseResultCode.SUCCESS);
                response.setStatus(1);
                response.setResult(JSONObject.toJSONString(smsObject));
                response.setExt(JSONObject.toJSONString(dataMap));
                return response;
            }*/
        } catch (Exception e) {
            logger.error("{}支付失败:", channelAccount.getChannelCode(), e);
            response.setCode(BaseResultCode.COMMON_FAIL);
            response.setErrorMsg("请求接口异常");
            return response;
        }
        return response;
    }

    @Override
    public ChannelResponse termination(ChannelTerminationCard channelTerminationCard, ChannelAccount channelAccount) {
        ChannelResponse response = new ChannelResponse(BaseResultCode.SUCCESS);
        response.setStatus(1);
        return response;
    }

    @Override
    public ChannelNotifyResponse orderNotify(ChannelNotifyRequest request, ChannelAccount channelAccount) {
        ChannelNotifyResponse channelNotifyResponse = new ChannelNotifyResponse();
        channelNotifyResponse.setOrderNo(request.getOrderNo());
        channelNotifyResponse.setStatus(OrderStatusEnum.NOT_PAY.getStatus());
        channelNotifyResponse.setResponseText("FAIL");
        boolean flag = AinongSignUtil.verifyNotifySign(request.getData(), channelAccount.getRsaKeyPub());
        if (!flag) {
            logger.error("{}支付验签失败，data={}", PayChannelEnum.AINONG.getChannelCode(), request.getData());
            return channelNotifyResponse;
        }
        JSONObject jsonObject = JSONObject.parseObject(request.getData());
        String status = jsonObject.getString("transStat");
        if ("1001".equalsIgnoreCase(status)) {
            channelNotifyResponse.setStatus(OrderStatusEnum.PAY_SUCCESS.getStatus());
            channelNotifyResponse.setOrderNo(request.getOrderNo());
            channelNotifyResponse.setResponseText("SUCCESS");
            return channelNotifyResponse;
        } else if ("1002".equalsIgnoreCase(status)) {
            channelNotifyResponse.setStatus(OrderStatusEnum.PAY_FAIL.getStatus());
            channelNotifyResponse.setOrderNo(request.getOrderNo());
            channelNotifyResponse.setResponseText("FAIL");
            return channelNotifyResponse;
        }
        return channelNotifyResponse;
    }

    @Override
    public ChannelNotifyResponse defrayNotify(ChannelNotifyRequest request, ChannelAccount channelAccount) {
        ChannelNotifyResponse response = new ChannelNotifyResponse();
        response.setOrderNo(request.getOrderNo());
        response.setStatus(OrderStatusEnum.NOT_PAY.getStatus());
        response.setResponseText("FAIL");
        logger.info("AinongDefray:defrayNotify,{}", "收到爱农代付回调请求:" + JSONObject.toJSONString(request));

        Map<String, String> resultMap = new HashMap<>();
        resultMap.put("returnCode", "0000");
        boolean flag = AinongSignUtil.verifyNotifySign(request.getData(), channelAccount.getRsaKeyPub());
        if (!flag) {
            logger.error("{}代付验签失败，data={}", PayChannelEnum.AINONG.getChannelCode(), request.getData());
            return response;
        }
        JSONObject jsonObject = JSONObject.parseObject(request.getData());
        String status = jsonObject.getString("transStat");
        if ("1001".equalsIgnoreCase(status)) {
            response.setStatus(OrderStatusEnum.PAY_SUCCESS.getStatus());
            response.setResponseText("SUCCESS");
            response.setOrderNo(request.getOrderNo());
            return response;
        } else if ("1002".equalsIgnoreCase(status)) {
            response.setStatus(OrderStatusEnum.PAY_FAIL.getStatus());
            response.setResponseText("FAIL");
            response.setOrderNo(request.getOrderNo());
            return response;
        }
        return response;
    }

    @Override
    public ChannelResponse payQuery(ChannelOrder channelOrder, ChannelAccount channelAccount) {
        ChannelResponse response = new ChannelResponse(BaseResultCode.SUCCESS);
        JSONObject data = AinongPay.buildPayQueryRequest(channelOrder.getChannelOrderNo(), channelAccount);
        JSONObject request = AinongCovert.buildParams(data, channelAccount.getChannelAccount(), channelOrder.getRechrageNo());
        String sign = AinongSignUtil.buildSign(request, channelAccount.getRsaKeyPri());
        request.put("signature", sign);
        logger.info("{} 支付查询请求参数，data={}", channelAccount.getChannelCode(), request.toJSONString());
        String result;
        try {
            String url = channelAccount.getChannelUrl() + "/order/singleQueryOrd.do";
            result = HttpClientUtil.invokeHttpPost(url, request.toJSONString());
            logger.info("{} 支付查询请求完成，result={}", channelAccount.getChannelCode(), result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            boolean flag = AinongSignUtil.verifySign(result, channelAccount.getRsaKeyPub());
            if (!flag) {
                logger.error("{} 支持查询验签失败，result={}", channelAccount.getChannelCode(), result);
                response.setCode(BaseResultCode.COMMON_FAIL);
                response.setErrorMsg("请求接口异常");
                return response;
            }
            if (jsonObject.getJSONObject("data").getString("respCode").equalsIgnoreCase("000000")) {
                response.setStatus(1);
                response.setCode(BaseResultCode.SUCCESS);
                response.setResult(JSONObject.toJSONString(jsonObject));
                return response;
            } else {
                response = AinongErrorTransfer.buildErrorResult(jsonObject.getJSONObject("data").getString("respCode"), jsonObject.getJSONObject("data").getString("respMsg"));
                response.setStatus(OrderStatusEnum.PAY_FAIL.getStatus());
                response.setResult(result);
            }
        } catch (Exception e) {
            logger.error("{}支付查询失败:", channelAccount.getChannelCode(), e);
            response.setCode(BaseResultCode.COMMON_FAIL);
            response.setErrorMsg("请求支付查询接口异常");
            return response;
        }
        return response;
    }

    @Override
    public ChannelResponse defray(ChannelDefray channelDefray, ChannelAccount channelAccount) {
        ChannelResponse response = new ChannelResponse(BaseResultCode.SUCCESS);
        JSONObject data = AinongDefray.buildDefrayRequest(channelDefray, channelAccount);
        JSONObject request = AinongCovert.buildParams(data, channelAccount.getChannelAccount(), channelDefray.getOrderNo());
        String sign = AinongSignUtil.buildSign(request, channelAccount.getRsaKeyPri());
        request.put("signature", sign);
        logger.info("{} 代付请求参数，data={}", channelAccount.getChannelCode(), request.toJSONString());
        String result;
        try {
            String url = channelAccount.getChannelUrl() + "/remit/singleRemit.do";
            result = HttpClientUtil.invokeHttpPost(url, request.toJSONString());
            logger.info("{} 代付请求完成，result={}", channelAccount.getChannelCode(), result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            boolean flag = AinongSignUtil.verifySign(result, channelAccount.getRsaKeyPub());
            if (!flag) {
                logger.error("{} 代付请求验签失败，result={}", channelAccount.getChannelCode(), result);
                response.setCode(BaseResultCode.COMMON_FAIL);
                response.setErrorMsg("请求接口异常");
                return response;
            }
            if ("0000".equalsIgnoreCase(jsonObject.getString("gateWayRespCode"))) {
                if (jsonObject.getJSONObject("data").getString("respCode").equalsIgnoreCase("000000")) {
                    response.setCode(BaseResultCode.SUCCESS);
                    response.setStatus(1);
                    response.setResult(JSONObject.toJSONString(jsonObject));
                    return response;
                } else {
                    response = AinongErrorTransfer.buildErrorResult(jsonObject.getJSONObject("data").getString("respCode"), jsonObject.getJSONObject("data").getString("respMsg"));
                    response.setResult(result);
                }
            } else {
                response = AinongErrorTransfer.buildErrorResult(jsonObject.getJSONObject("data").getString("respCode"), jsonObject.getJSONObject("data").getString("respMsg"));
                response.setResult(result);
                response.setStatus(OrderStatusEnum.PAY_FAIL.getStatus());
            }
        } catch (Exception e) {
            logger.error("{}代付失败:", channelAccount.getChannelCode(), e);
            response.setCode(BaseResultCode.COMMON_FAIL);
            response.setErrorMsg("请求代付接口异常");
            return response;
        }
        return response;
    }

    @Override
    public ChannelResponse defrayQuery(UserCash userCash, ChannelAccount channelAccount) {
        ChannelResponse response = new ChannelResponse(BaseResultCode.SUCCESS);
        JSONObject data = AinongDefray.buildDefrayQueryRequest(userCash, channelAccount);
        JSONObject request = AinongCovert.buildParams(data, channelAccount.getChannelAccount(), userCash.getCashNo());
        String sign = AinongSignUtil.buildSign(request, channelAccount.getRsaKeyPri());
        request.put("signature", sign);
        logger.info("{} 支付查询请求参数，data={}", channelAccount.getChannelCode(), request.toJSONString());
        String result;
        try {
            String url = channelAccount.getChannelUrl() + "/order/singleQueryOrd.do";
            result = HttpClientUtil.invokeHttpPost(url, request.toJSONString());
            logger.info("{} 代付查询请求完成，result={}", channelAccount.getChannelCode(), result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            boolean flag = AinongSignUtil.verifySign(result, channelAccount.getRsaKeyPub());
            if (!flag) {
                logger.error("{} 代付查询验签失败，result={}", channelAccount.getChannelCode(), result);
                response.setCode(BaseResultCode.COMMON_FAIL);
                response.setErrorMsg("请求接口异常");
                return response;
            }
            JSONObject jsonData = jsonObject.getJSONObject("data");
            if(jsonData == null){
                response.setCode(BaseResultCode.COMMON_FAIL);
                response.setErrorMsg("请求接口异常");
                return response;
            }
            if (jsonData.getString("respCode").equalsIgnoreCase("000000")) {
                response.setStatus(CashStatusEnum.SUCCESS.getStatus());
                response.setCode(BaseResultCode.SUCCESS);
                response.setResult(JSONObject.toJSONString(jsonObject));
                return response;
            }else if("EB2009".equalsIgnoreCase(jsonData.getString("respCode"))){
                response.setStatus(CashStatusEnum.FAIL.getStatus());
                response.setCode(BaseResultCode.SUCCESS);
                response.setResult(JSONObject.toJSONString(jsonObject));
                return response;
            } else {
                response = AinongErrorTransfer.buildErrorResult(jsonObject.getJSONObject("data").getString("respCode"), jsonObject.getJSONObject("data").getString("respMsg"));
                response.setResult(result);
            }
        } catch (Exception e) {
            logger.error("{}代付查询失败:", channelAccount.getChannelCode(), e);
            response.setCode(BaseResultCode.COMMON_FAIL);
            response.setErrorMsg("请求代付查询接口异常");
            return response;
        }
        return response;
    }

    @Override
    public ChannelResponse doChargeSms(ChannelChargeSms channelChargeSms, ChannelAccount channelAccount) {
        ChannelResponse response = new ChannelResponse(BaseResultCode.SUCCESS);
        JSONObject data = AinongPay.buildSmsRequest(channelChargeSms, channelAccount);
        JSONObject request = AinongCovert.buildParams(data, channelAccount.getChannelAccount(), channelChargeSms.getOrderNo());
        String sign = AinongSignUtil.buildSign(request, channelAccount.getRsaKeyPri());
        request.put("signature", sign);
        logger.info("{} 短信验证请求参数，data={}", channelAccount.getChannelCode(), request.toJSONString());
        String result;
        try {
            String url = channelAccount.getChannelUrl() + "/quickPay/payConfirm.do";
            result = HttpClientUtil.invokeHttpPost(url, request.toJSONString());
            logger.info("{}  短信验证请求完成，result={}", channelAccount.getChannelCode(), result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            boolean flag = AinongSignUtil.verifySign(result, channelAccount.getRsaKeyPub());
            if (!flag) {
                logger.error("{} 充值请求验签失败，result={}", channelAccount.getChannelCode(), result);
                response.setCode(BaseResultCode.COMMON_FAIL);
                response.setErrorMsg("请求接口异常");
                return response;
            }
            if (jsonObject.getJSONObject("data").getString("respCode").equalsIgnoreCase("000000")) {
                response.setCode(BaseResultCode.SUCCESS);
                response.setStatus(1);
                response.setResult(result);
                return response;
            } else {
                response = AinongErrorTransfer.buildErrorResult(jsonObject.getJSONObject("data").getString("respCode"), jsonObject.getJSONObject("data").getString("respMsg"));
                logger.error("请求支付验证接口失败:" + jsonObject.getJSONObject("data").getString("respMsg"));
                return response;
            }
        } catch (Exception e) {
            logger.error("{}短信验证失败:", channelAccount.getChannelCode(), e);
            response.setCode(BaseResultCode.COMMON_FAIL);
            response.setErrorMsg("请求接口异常");
            return response;
        }
    }

    @Override
    public ChannelResponse balanceQuery(ChannelAccount channelAccount) {
        ChannelResponse response = new ChannelResponse(BaseResultCode.SUCCESS);
        response.setCode(BaseResultCode.INTERNAL_ERROR);
        response.setErrorMsg("暂不支持此功能");
        return response;
    }
}
